﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics.Contracts;
using Kooboo.Collections;
using System.ComponentModel.Composition;

namespace Kooboo.Commerce.Repositories
{
    [Export(typeof(IOrderRepository))]
    public partial class EntityRepositories:IOrderRepository
    {
    
        public IQueryable<IOrder> Orders
        {
            get
            {
                return this.DataReaderContext.Orders;
            }
        }

        public void Post(IOrder order)
        {
            Contract.Requires(order != null);

            Order item = new Order();
          
            CopyTo(order, item);
            order.Customer = null;

            this.DataWriterContext.Orders.InsertOnSubmit(item);
            this.DataWriterContext.SubmitChanges();



            foreach (var i in order.OrderItems)
            {
                var orderItem = new OrderItem();
                orderItem.Order = item;
                this.DataWriterContext.OrderItems.InsertOnSubmit(orderItem);
                this.DataWriterContext.SubmitChanges();
                i.Id = orderItem.Id;

                CopyTo(i, item, orderItem); 
            }

        
            order.Id = item.Id;
        }

  
        public void Put(IOrder order)
        {
            Contract.Requires(order != null);

            var item = this.DataWriterContext.Orders
                .Where(i => i.Id == order.Id)
                .FirstOrDefault();


            if (item == null)
            {
                throw new KeyNotFoundException("Order: " + order.Id);
            }


            CopyTo(order, item);

            var items = this.DataWriterContext.OrderItems.Where(i => i.OrderId == item.Id).ToList();

            var result = items.Compare(order.OrderItems, (i1, i2) => i1.Id == i2.Id, (i1, i2) =>
            {
                CopyTo(i2,item, (OrderItem)i1);
            });


            foreach (var i in result.Deleted)
            {
                var find = this.DataWriterContext.OrderItems
                    .Where(n => n.Id == i.Id)
                    .FirstOrDefault();

                this.DataWriterContext.OrderItems.DeleteOnSubmit((OrderItem)i);
            }


            foreach (var i in result.Added)
            {
                var orderItem = new OrderItem();

                this.DataWriterContext.OrderItems.InsertOnSubmit(orderItem);

                CopyTo(i, item, orderItem);

                i.Id = orderItem.Id;
            }



            this.DataWriterContext.SubmitChanges();


        }

        public void Delete(IOrder order)
        {
            if (order != null)
            {
                var item = this.DataWriterContext.Orders
                .Where(i => i.Id == order.Id)
                .FirstOrDefault();

                if (item != null)
                {
                    this.DataWriterContext.Orders.DeleteOnSubmit(item);
                    this.DataWriterContext.OrderItems.DeleteAllOnSubmit(this.DataWriterContext.OrderItems.Where(i => i.OrderId == item.Id));
                    this.DataWriterContext.SubmitChanges();
                }
            }
        }

        #region CopyTo
        private void CopyTo(IOrderItem data,Order order, OrderItem orderItem)
        {
            orderItem.Discount = data.Discount;
            orderItem.Order = order;
            orderItem.ProductId = data.ProductId;
            orderItem.ProductName = data.ProductName;
            orderItem.Quantity = data.Quantity;
            orderItem.SaleItemId = data.SaleItemId;
            orderItem.SKU = data.SKU;
            orderItem.SubTotal = data.SubTotal;
            orderItem.TaxCost = data.TaxCost;
            orderItem.Total = data.Total;
            orderItem.UnitPrice = data.UnitPrice;

            var fields = this.DataWriterContext.OrderItemCustomFields.Where(i => i.OrderItemId == orderItem.Id);
            this.DataWriterContext.OrderItemCustomFields.DeleteAllOnSubmit(fields);
            this.DataWriterContext.SubmitChanges();

            foreach (var n in data.OrderItemCustomFields)
            {
                var field = new OrderItemCustomField
                {
                    Name = n.Name,
                    OrderItem = orderItem,
                    Value = n.Value
                };

                this.DataWriterContext.OrderItemCustomFields.InsertOnSubmit(field);
                this.DataWriterContext.SubmitChanges();    
                n.Id = field.Id;
            }

            var variations = this.DataWriterContext.OrderItemVariations.Where(i => i.OrderItemId == orderItem.Id);
            this.DataWriterContext.OrderItemVariations.DeleteAllOnSubmit(variations);

            foreach (var n in data.OrderItemVariations)
            {
                var variation = new OrderItemVariation
                {
                    Name = n.Name,
                    OrderItem = orderItem,
                    Value = n.Value
                };

                this.DataWriterContext.OrderItemVariations.InsertOnSubmit(variation);
                this.DataWriterContext.SubmitChanges();
                n.Id = variation.Id;
            }
        }

        private void CopyTo(IOrder order, Order item)
        {
            item.Address1 = order.Address1;
            item.Address2 = order.Address2;

            if (order.Cart == null)
            {
                item.CartId = null;
            }
            else
            {
                item.CartId = order.Cart.Id;
            }

            item.City = order.City;
            item.Country = order.Country;
            item.Coupon = order.Coupon;

            item.CustomerId = order.Customer.Id;
            item.Discount = order.Discount;
            
            item.FirstName = order.FirstName;
            item.InsuredAmount = order.InsuredAmount;
            item.InvoiceAddress1 = order.InvoiceAddress1;
            item.InvoiceAddress2 = order.InvoiceAddress2;
            item.InvoiceCity = order.InvoiceCity;
            item.InvoiceCountry = order.InvoiceCountry;
            item.InvoiceFirstName = order.InvoiceFirstName;
            item.InvoiceLastName = order.InvoiceLastName;
            item.InvoicePhone = order.InvoicePhone;
            item.InvoicePostcode = order.InvoicePostcode;
            item.InvoiceState = order.InvoiceState;
            item.IsCompleted = order.IsCompleted;
            item.LastName = order.LastName;
            item.OrderDate = order.OrderDate;
            item.OrderStatus = (int)order.OrderStatus;
            item.PaymentMethodCost = order.PaymentMethodCost;
            item.PaymentName = order.PaymentName;

            item.Phone = order.Phone;
            item.Postcode = order.Postcode;
            //item.Promotions
            item.Remark = order.Remark;
            item.ShippingCost = order.ShippingCost;
            item.ShippingId = order.ShippingId;
            item.ShippingTrackingCode = order.ShippingTrackingCode;

            item.State = order.State;
            item.SubTotal = order.SubTotal;
            item.Total = order.Total;
            item.TotalDiscount = order.TotalDiscount;
            item.TotalTaxCost = order.TotalTaxCost;
            item.TotalWeight = order.TotalWeight;
        }
        #endregion

    }
}
